package strategy

import (
	"fmt"
	"reflect"
	"sort"
	"strconv"
	"strings"
	"super/constant"
	"super/db"
	"super/global"
	"unicode/utf8"
)

type DbStrategy struct{}

func (dbs DbStrategy) Init() {
	if db.Dao == nil {
		err := db.InitDB()
		if err != nil {
			fmt.Println(err)
			fmt.Print("super>")
			return
		}
		global.CurStatus = constant.Db
		fmt.Println("db connect successful")
		fmt.Print("db>")
		return
	}
	fmt.Println("已经连接了")
	global.CurStatus = constant.Db
	fmt.Print("db>")
}

func (dbs DbStrategy) Handle(str string) {
	if str == "n" {
		if globPage.total == 0 {
			fmt.Println("没有数据")
			fmt.Print("db>")
			return
		}
		//下一页

		if globPage.curPage == globPage.pageCount-1 {
			fmt.Println("最后一页了")
			fmt.Print("db>")
			return
		}

		globPage.curPage = globPage.curPage + 1
		if err := getPage(&globPage); err != nil {
			fmt.Println(err)
			fmt.Print("db>")
			return
		}

		showTable()
		fmt.Print("db>")
		return
	}

	if str == "p" {
		if globPage.total == 0 {
			fmt.Println("没有数据")
			fmt.Print("db>")
			return
		}

		//上一页
		if globPage.curPage == 0 {
			fmt.Println("已经是第一页了")
			fmt.Print("db>")
			return
		}
		globPage.curPage = globPage.curPage - 1
		if err := getPage(&globPage); err != nil {
			fmt.Println(err)
			fmt.Print("db>")
			return
		}

		showTable()
		fmt.Print("db>")
		return
	}

	if strings.HasSuffix(str, ";") {
		str = str[:len(str)-1]
	}

	initGlobPage()
	globPage.sql = str

	if err := getPage(&globPage); err != nil {
		fmt.Println(err)
		fmt.Print("db>")
		return
	}

	showTable()

	fmt.Print("db>")
}

type page struct {
	data      []map[string]interface{}
	curPage   int
	total     int
	pageSize  int
	sql       string
	pageCount int
}

var globPage page

func initGlobPage() {
	globPage = page{}
	globPage.pageSize = db.PageSize
}

func getPage(p *page) error {
	maps := make([]map[string]interface{}, 0)
	pageSql := p.sql + " limit ?,?"
	rows, err := db.Dao.Query(pageSql, p.curPage*p.pageSize, p.pageSize)
	if err != nil {
		return err
	}

	columns, _ := rows.Columns()
	for rows.Next() {
		m := make(map[string]interface{}, len(columns))
		vals := make([]interface{}, len(columns))
		for i, _ := range columns {
			var v interface{}
			vals[i] = &v
		}
		rows.Scan(vals...)
		for i, column := range columns {
			v := *vals[i].(*interface{})
			v = fmt.Sprintf("%s", v)
			m[column] = v
		}
		maps = append(maps, m)
	}
	rows.Close()

	var totalCount int
	if err := db.Dao.Get(&totalCount, "select count(*) totalCount from ("+p.sql+") t"); err != nil {
		return err
	}

	p.data = maps
	p.total = totalCount

	var pageCount int
	if p.total < p.pageSize {
		pageCount = 1
	} else {
		pageCount = p.total / p.pageSize
		if p.total%p.pageSize > 0 {

			pageCount += 1
		}
	}
	p.pageCount = pageCount
	return nil
}
func showTable() {
	maps := globPage.data
	totalCount := globPage.total
	fmt.Println("------------------------------------------------------------------------------------------------------------------------------------------------")
	if len(maps) == 0 {
		fmt.Println("没有查询到!")
		return
	}

	lenMap := maxCellLength(maps)

	length := len(strconv.Itoa(len(maps)))

	fmt.Print(emptyCell(length) + " |")
	var keys []string
	for k, _ := range maps[0] {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, k := range keys {
		fmt.Printf(" %*s |", lenMap[k], k)
	}
	fmt.Println()
	fmt.Println("------------------------------------------------------------------------------------------------------------------------------------------------")

	for i, m := range maps {
		fmt.Printf("%*d", length, i+1)
		fmt.Print(" |")
		for _, k := range keys {
			//fmt.Print(k)
			v := m[k]
			if v == nil {
				fmt.Printf(" %s |", emptyCell(lenMap[k]))
			} else {
				kind := reflect.TypeOf(v).Kind()
				if kind == reflect.String {
					fmt.Printf(" %-*s |", lenMap[k], v)
				} else {
					fmt.Printf(" %*v |", lenMap[k], v)
				}
			}
		}
		fmt.Println()
	}

	fmt.Println("------------------------------------------------------------------------------------------------------------------------------------------------")
	fmt.Printf("共%d条,当前显示%d条,当前第%d页,共%d页下一页输入n,上一页输入p\n", totalCount, len(maps), globPage.curPage+1, globPage.pageCount)
}

func emptyCell(length int) string {
	var empty string
	for i := 0; i < length; i++ {
		empty += " "
	}
	return empty
}

func maxCellLength(maps []map[string]interface{}) map[string]int {
	lenMap := make(map[string]int, len(maps))
	for k, _ := range maps[0] {
		var maxLen int = len(k)
		for _, m := range maps {
			v := m[k]
			if v == nil {
				continue
			}
			kind := reflect.TypeOf(v).Kind()
			if kind == reflect.String {
				l := utf8.RuneCountInString(v.(string))
				if l > maxLen {
					maxLen = l
				}
			}
		}

		lenMap[k] = maxLen
	}
	return lenMap
}
